﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using GameSchoolApplication.Models;
using GameSchoolApplication.Models.ViewModels;

namespace GameSchoolApplication.Repositories
{
    public class CourseLevelRepository
    {
        gsDBDataContext link = new gsDBDataContext();

        /// <summary>
        /// Returns level with the specified ID
        /// Precondition: ID must exist
        /// Postcondition: Level has been returned
        /// Author: Aron Mar mod. by Alma
        /// Date: 7.5.12
        /// </summary>
        /// <param name="ID">ID of assignment to get</param>
        public CourseLevel getLevelByID(int ID)
        {
            CourseLevel lev = (from l in link.CourseLevels
                               where l.lvlID == ID
                               select l).First();
            return lev; 
        }

        /// <summary>
        /// Returns a queryable list of all assignments of the course with the specified ID
        /// Precondition: course must exist
        /// Postcondition: All assignments of the course have been returned
        /// Author: Aron Mar
        /// Date: 4.5.12
        /// </summary>
        /// <param name="courseID">The ID of the course</param>
        public IQueryable<CourseLevel> getLevelsOfCourse(int courseID)
        {
            IQueryable<CourseLevel> levels = (from l in link.CourseLevels
                                              where l.cID == courseID
                                              select l);
            return levels;
        }

        /// <summary>
        /// Returns a query-able list containing all levels
        /// Precondition: 
        /// Postcondition: List of levels has been returned
        /// Author: Aron Mar mod. by Alma
        /// Date: 7.5.12
        /// </summary>
        public IQueryable<CourseLevel> getAllLevels()
        {
            return link.CourseLevels;
        }

        /// <summary>
        /// Adds level to database
        /// Precondition: The user is a teacher or admin
        /// Postcondition: Level has been added to database
        /// Author: Aron Mar mod. by Alma
        /// Date: 7.5.12
        /// </summary>
        public bool addLevel(CourseLevel level)
        {
            try
            {
                link.CourseLevels.InsertOnSubmit(level);
                save(); 
            }
            catch (Exception)
            {
                return false;
            }
            return true; 
        }

        /// <summary>
        /// Edits assignment
        /// Precondition: User must be an administrator/teacher and the assignment must exist
        /// Postcondition: Level information has been updated in the database
        /// Author: Aron Mar mod. by Alma
        /// Date: 7.5.12
        /// </summary>
        public bool editLevel(CourseLevel level)
        {
            try
            {
                var lev = (from l in link.CourseLevels
                            where l.lvlID == level.lvlID
                            select l).First();

                lev.name = level.name;
                lev.pointReward = level.pointReward;
                lev.lvlDesc = level.lvlDesc;
                lev.isOpen = level.isOpen;

                save();

                return true;
            }
            catch (Exception)
            {
                return false;
            }
            
        }

        /// <summary>
        /// Saves changes to database
        /// Precondition:
        /// Postcondition: Database has been updated
        /// Author: Aron og Bjarmi
        /// Date: 03.05.2012
        /// </summary>
        public void save()
        {
            link.SubmitChanges();
        }

        /// <summary>
        /// returns a list of LevelIcons for a course
        /// Precondition:
        /// Postcondition: List has been returned
        /// Author: Aron og Bjarmi
        /// Date: 03.05.2012
        /// </summary>
        /// <param name="cID">Course ID</param>
        /// <param name="uID">User ID</param>
        public List<LevelIcon> getLevelIconsOfCourse(int cID, string uID)
        {
            List<LevelIcon> lvls = new List<LevelIcon>();

            foreach (CourseLevel a in link.CourseLevels.Where(x => x.cID == cID))
            {
                LevelIcon temp = new LevelIcon();

                temp.levelID = a.lvlID;
                
                temp.name = a.name;
                var result = (from p in link.StudentProgresses
                                 where p.stID == uID && p.lvlID == a.lvlID
                                 select p.lvlProgress).FirstOrDefault();

                temp.progress = Convert.ToInt32(result == null ? 0 : result);

                temp.assignmentCount = (from c in link.Assignments
                                        where c.lvlID == a.lvlID
                                        select c.assignmentID).Count();
                if ((from t in link.TeachesClasses
                     where t.courseID == cID && t.teacherID == uID
                     select t).Count() == 0)
                {
                    var res = (from p in link.UserFinishedLevels
                               from c in link.CourseLevels
                               where p.userID == uID && c.cID == cID && p.clID == c.lvlID
                               select c.num);
                    if (res.Count() > 0)
                    {
                        temp.hasAccess = (a.num > res.Max() + 1 ? false : true); // res.Max() hæsta lvl sem er búið
                    }
                    else
                        temp.hasAccess = (a.num == 1 ? true : false);
                }
                else
                    temp.hasAccess = true;
                
                
                lvls.Add(temp);
            }

            return lvls;
        }

    }
}